package cn.tedu.douguo.user.service.impl;

import cn.tedu.douguo.commons.ex.ServiceException;
import cn.tedu.douguo.commons.web.ServiceCode;

import cn.tedu.douguo.user.mapper.UserMapper;
import cn.tedu.douguo.user.pojo.entity.User;
import cn.tedu.douguo.user.pojo.param.UserLoginInfoParam;
import cn.tedu.douguo.user.pojo.param.UserRegInfoParam;
import cn.tedu.douguo.user.pojo.vo.UserLoginInfoVO;
import cn.tedu.douguo.user.pojo.vo.UserNavInfoVO;
import cn.tedu.douguo.user.security.UserDetails;
import cn.tedu.douguo.user.service.UserService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Value("${douguo.jwt.secret-key}")
    private String secretKey;
    @Value("${douguo.jwt.duration-in-minute}")
    private Long durationInMinute;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String register(UserRegInfoParam userRegInfoParam) {

        //检查用户名是否存在
        log.debug("开始处理【用户注册】的业务，参数：{}", userRegInfoParam);
        // 检查管理员用户名是否被占用，如果被占用，则抛出异常
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userRegInfoParam.getUsername());
        int countByUsername = userMapper.selectCount(queryWrapper);
        if (countByUsername > 0) {
            String message = "注册用户失败，用户名已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //手机号  本业务已经停用
        // 检查是否被占用，如果被占用，则抛出异常
//        queryWrapper.eq("phone", userRegInfoParam.getPhone());
//        int countByPhone = userMapper.selectCount(queryWrapper);
//        if (countByPhone > 0) {
//            String message = "注册用户失败，手机号已经被占用！";
//            log.warn(message);
//            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
//        }

        User user=new User();

        BeanUtils.copyProperties(userRegInfoParam,user);

        String rawPassword = user.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        user.setPassword(encodedPassword);
//        本业务停用
        //签名和头像是否null，如果是null，添加默认值
//        String signature=userRegInfoParam.getSignature();
//        if(signature==null){
//            signature="一个文明的签名..";
//            user.setSignature(signature);
//        }
        String avatar = userRegInfoParam.getAvatar();
        if(avatar==null){
            avatar="https://img.zcool.cn/community/01e0ae58ae3d72a801219c77fadb52.png@1280w_1l_2o_100sh.png";
            user.setAvatar(avatar);
        }

        //设置达人  、 启用、 时间
        user.setTalent(0).setEnable(1).setJoinTime(LocalDateTime.now());
        userMapper.insert(user);

        //   todo  注册完成后直接返回jwt的功能
        return null;
    }



    @Override
    public String login(UserLoginInfoParam userLoginInfoParam) {


        log.debug("开始处理【用户登录】的业务，参数：{}", userLoginInfoParam);
        // 创建认证时所需的参数对象
        Authentication authentication = new UsernamePasswordAuthenticationToken(userLoginInfoParam.getUsername(),userLoginInfoParam.getPassword());
        // 执行认证，并获取认证结果
        Authentication authenticateResult
                = authenticationManager.authenticate(authentication);
        log.debug("验证登录完成，认证结果：{}", authenticateResult);

        // 从认证结果中取出所需的数据
        Object principal = authenticateResult.getPrincipal();
        //转换为UserDetails类型
        UserDetails userDetails = (UserDetails) principal;
        Collection<GrantedAuthority> authorities = userDetails.getAuthorities();

        // 生成JWT
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", userDetails.getId());
        claims.put("username", userDetails.getUsername());
        claims.put("authoritiesJsonString", JSON.toJSONString(authorities));
        String jwt = Jwts.builder()
                // Header
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                // Payload
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + durationInMinute * 1000 * 60))
                // Verify Signature
                .signWith(SignatureAlgorithm.HS256, secretKey)
                // 生成
                .compact();
        log.debug("生成了此用户的信息对应的JWT：{}", jwt);
        return jwt;

    }

    @Override
    public UserNavInfoVO getUserInfoById(Long userId) {

        UserNavInfoVO userInfo= userMapper.getUserInfoById(userId);
        return userInfo;
    }

    @Override
    public void logout(String jwt) {
        log.debug("开始处理【退出登录】的业务，参数：{}", jwt);
//     todo   从Redis删除jwt
//        userMapper.delete(jwt);
    }


}
